using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls;
using System.Drawing;
using Alogient.Cameleon.Forms.Sdk;
using Alogient.Cameleon.Forms.Sdk.Items;
using System.Web.UI;
using Alogient.Cameleon.Sdk;
using System.Collections;

namespace Alogient.Cameleon.Forms.Sdk.Controls
{
    internal class FormCheckbox : CMFormElement
    {
        protected const string OTHER_VALUE = "__OTHER";
        protected const string OTHER_TEXTBOX_ID_FORMAT = "Other_Textbox_{0}";
        public override string Value
        {
            get
            {
                CheckBoxList checkboxes = this.FindControl(string.Format("checkboxes_{0}", this.ID)) as CheckBoxList;

                StringBuilder sb = new StringBuilder();
                foreach(ListItem item in checkboxes.Items)
                {
                    if (item.Selected)
                    {
                        if (item.Value == OTHER_VALUE)
                        {
                            //Get Textbox value
                            TextBox otherTextbox = this.FindControl(string.Format(OTHER_TEXTBOX_ID_FORMAT, this.ID)) as TextBox;
                            sb.AppendFormat("{0};", otherTextbox.Text);
                        }
                        else
                        {
                            sb.AppendFormat("{0};", item.Value);
                        }
                    }
                }
                
                return sb.ToString();
            }
        }
        public override string[] Values
        {
            get
            {
                CheckBoxList checkboxes = this.FindControl(string.Format("checkboxes_{0}", this.ID)) as CheckBoxList;

                ArrayList list = new ArrayList();
                //StringBuilder sb = new StringBuilder();
                foreach (ListItem item in checkboxes.Items)
                {
                    if (item.Selected)
                    {
                        if (item.Value == OTHER_VALUE)
                        {
                            //Get Textbox value
                            TextBox otherTextbox = this.FindControl(string.Format(OTHER_TEXTBOX_ID_FORMAT, this.ID)) as TextBox;
                            list.Add(otherTextbox.Text);
                        }
                        else
                        {
                            list.Add(item.Value);
                        }
                    }
                }

                return list.ToArray(typeof(string)) as string[];
            }
        }

        internal FormCheckbox(Forms.Sdk.Items.Checkbox element) : base(element)
        {
            PlaceHolder checkboxPh = new PlaceHolder();

            System.Web.UI.WebControls.CheckBoxList checkboxes = new CheckBoxList();
            checkboxes.ID = string.Format("checkboxes_{0}", this.ID);

            foreach (FormElementChoice choice in element.Choices)
            {
                if ((CMServices.IsLive && choice.VisibleLive) || (!CMServices.IsLive && choice.VisiblePreview))
                {
                    ListItem checkbox = new ListItem();
                    checkbox.Text = choice.Name;
                    checkbox.Value = choice.ID.ToString();// Value;

                    if (choice.ID == element.DefaultValue)
                    {
                        checkbox.Selected = true;
                    }

                    checkboxes.Items.Add(checkbox);
                }
            }

            checkboxPh.Controls.Add(checkboxes);

            if (element.Other)
            {
                ListItem checkbox = new ListItem();

                checkbox.Text = element.OtherLabel;
                checkbox.Value = OTHER_VALUE;

                checkboxes.Items.Add(checkbox);

                TextBox otherTextbox = new TextBox();
                otherTextbox.ID = string.Format(OTHER_TEXTBOX_ID_FORMAT, this.ID);

                checkboxPh.Controls.Add(otherTextbox);
            }

            Label label = new Label();
            label.Text = element.Label;

            label.CssClass = string.Format("{0}Label", element.CSS);

            #region Validators

            PlaceHolder phValidators = new PlaceHolder();

            //Required
            if (element.Required)
            {
                Label redStar = new Label();
                redStar.ForeColor = Color.Red;
                redStar.Text = "*";

                RequiredFieldValidatorForCheckBoxLists required = new RequiredFieldValidatorForCheckBoxLists();
                required.ID = string.Format("required_{0}_{1}", element.FormID, element.ID);
                required.ControlToValidate = checkboxes.ID;
                required.ValidationGroup = element.FormID.ToString();
                required.Display = ValidatorDisplay.Dynamic;
                required.ErrorMessage = string.Format(Alogient.Cameleon.Forms.Sdk.Util.WebUtil.GetValidatorRessource("Required"), element.Label);
            
                phValidators.Controls.Add(redStar);
                phValidators.Controls.Add(required);
            }

            //Minimum Selected
            if (element.MinimumSelected > 0)
            {
                CustomValidator minimumSelected = new CustomValidator();
                minimumSelected.Attributes.Add("MinLength", element.MinimumSelected.ToString());
                minimumSelected.ID = string.Format("minimumSelected_", this.ID);
                minimumSelected.Attributes.Add("ControlToValidate", checkboxes.ID);
                minimumSelected.ValidationGroup = element.FormID.ToString();
                minimumSelected.Display = ValidatorDisplay.Dynamic;
                minimumSelected.ErrorMessage = string.Format(Alogient.Cameleon.Forms.Sdk.Util.WebUtil.GetValidatorRessource("MinSelected"), element.Label, element.MinimumSelected); 
                minimumSelected.ServerValidate += new ServerValidateEventHandler(minimumSelected_ServerValidate);

                phValidators.Controls.Add(minimumSelected);
            }

            //Maximum Selected
            if (element.MaximumSelected > 0 && element.MaximumSelected < element.Choices.Count)
            {
                CustomValidator maximumSelected = new CustomValidator();
                maximumSelected.Attributes.Add("MaxLength", element.MaximumSelected.ToString());
                maximumSelected.ID = string.Format("maximumSelected_", this.ID);
                maximumSelected.Attributes.Add("ControlToValidate", checkboxes.ID);
                //maximumSelected.ControlToValidate = checkboxes.ID;
                maximumSelected.ValidationGroup = element.FormID.ToString();
                maximumSelected.Display = ValidatorDisplay.Dynamic;
                maximumSelected.ErrorMessage = string.Format(Alogient.Cameleon.Forms.Sdk.Util.WebUtil.GetValidatorRessource("MaxSelected"), element.Label, element.MaximumSelected); 
                maximumSelected.ServerValidate += new ServerValidateEventHandler(maximumSelected_ServerValidate);

                phValidators.Controls.Add(maximumSelected);
            }

            #endregion

            GenerateRow(element, label, checkboxPh, phValidators);
        }

        void maximumSelected_ServerValidate(object source, ServerValidateEventArgs args)
        {
            CustomValidator validator = source as CustomValidator;
            int maxLength = int.MaxValue;
            int.TryParse(validator.Attributes["MaxLength"], out maxLength);

            args.IsValid = args.IsValid && CountSelected(validator) <= maxLength;
        }

        protected void minimumSelected_ServerValidate(object source, ServerValidateEventArgs args)
        {
            CustomValidator validator = source as CustomValidator;
            int minLength = 0;
            int.TryParse(validator.Attributes["MinLength"], out minLength);

            args.IsValid = args.IsValid && CountSelected(validator) >= minLength;
        }

        protected int CountSelected(CustomValidator validator)
        {
            int countSelected = 0;

            CheckBoxList checkboxes = this.FindControl(validator.Attributes["ControlToValidate"]) as CheckBoxList;

            foreach (ListItem check in checkboxes.Items)
            {
                if (check.Selected)
                {
                    countSelected++;
                }
            }

            return countSelected;
        }
    }

    //http://www.4guysfromrolla.com/webtech/tips/t040302-1.shtml
    internal class RequiredFieldValidatorForCheckBoxLists :
                      System.Web.UI.WebControls.BaseValidator
    {
        private ListControl _listctrl;

        public RequiredFieldValidatorForCheckBoxLists()
        {
            base.EnableClientScript = false;
        }

        protected override bool ControlPropertiesValid()
        {
            Control ctrl = FindControl(ControlToValidate);

            if (ctrl != null)
            {
                _listctrl = (ListControl)ctrl;
                return (_listctrl != null);
            }
            else
                return false;  // raise exception
        }

        protected override bool EvaluateIsValid()
        {
            return _listctrl.SelectedIndex != -1;
        }
    }
}
